package com.sniper.web.action.admin;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.sniper.data.DataValues;
import com.sniper.model.AdminGroup;
import com.sniper.model.AdminUser;
import com.sniper.mybatis.service.impl.AdminGroupService;
import com.sniper.utils.DataUtil;
import com.sniper.utils.FilesUtil;
import com.sniper.utils.PageUtil;
import com.sniper.utils.ValidateUtil;
import com.sniper.web.searchUtils.BaseSearch;
import com.sniper.web.utils.ControllerUtils;
import com.sniper.web.utils.ParamsToHtml;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RequestMapping("${adminPath}/admin-user")
@Controller
public class AdminUserController extends AdminBaseController {

    @Resource
    private AdminGroupService adminGroupService;


    // 用户组列表
    public List<AdminGroup> getAdminGroups() {
        return adminGroupService.query("select", null);
    }

    @RequiresPermissions("admin:user:view")
    @RequestMapping("/")
    public String index(Map<String, Object> map, BaseSearch search) {


        ParamsToHtml toHtml = new ParamsToHtml();
        toHtml.setSniperUrl("/admin-user/delete");

        Map<String, String> menu = new HashMap<>();
        menu.put("true", "是");
        menu.put("false", "否");

        toHtml.addMapValue("enabled", menu);

        Map<String, String> ispublic = new HashMap<>();
        ispublic.put("true", "是");
        ispublic.put("false", "否");

        toHtml.addMapValue("locked", ispublic);

        Map<String, String> keys = new HashMap<>();
        keys.put("enabled", "启用");
        keys.put("locked", "锁定");

        toHtml.setKeys(keys);

        Map<String, Object> params = new HashMap<>();

        if (ValidateUtil.isValid(search.getName())) {
            params.put("name", search.getName());
        }

        if (ValidateUtil.isValid(search.getChannel())) {
            params.put("gid", search.getChannel());
        }

        params.put("order", "u.ctime desc");
        PageUtil<AdminUser> page = adminUserService.page(request, search.getLimit(), params);

        map.put("page", page);
        map.put("sniperMenu", toHtml);
        map.put("adminGroups", getAdminGroups());
        return forward("/admin/admin-user/index.jsp");
    }

    @RequiresPermissions("admin:user:insert")
    @RequestMapping(value = "insert", method = RequestMethod.GET)
    public String insert(Map<String, Object> map) {

        map.put("adminUser", new AdminUser());
        map.put("adminGroups", getAdminGroups());
        map.put("sexs", DataValues.sexs);
        return forward("/admin/admin-user/save-input.jsp");

    }

    @ResponseBody
    @RequiresPermissions("admin:user:insert")
    @RequestMapping(value = "insert", method = RequestMethod.POST)
    public ControllerUtils.CallBackResult insert(@Validated AdminUser adminUser,
                                                 BindingResult result,
                                                 @RequestParam(value = "password_c", required = false) String password_c,
                                                 @RequestParam(value = "sign", required = false) Boolean sign,
                                                 @RequestParam(value = "adminGroups", required = false) String[] adminGroups)
            throws Exception {

        return new ControllerUtils().ajaxPostResult(result, callBackResult -> {

            setAdminGroups(adminGroups, adminUser);
            if (ValidateUtil.isValid(password_c)) {
                adminUser.setPassword(DigestUtils.sha1Hex(password_c));
            }

            if (ValidateUtil.isValid(sign) && sign) {
                adminUser.setSignCode(FilesUtil.getUUIDName("", true));
            }

            try {
                if (ValidateUtil.isValid(adminUser.getSiteids())) {
                    ObjectMapper objectMapper = new ObjectMapper();
                    String siteid = objectMapper
                            .writeValueAsString(adminUser.getSiteids());
                    adminUser.setSiteid(siteid);
                }
                adminUser.setId(FilesUtil.getUUIDName("", false));
                adminUserService.insert(adminUser);
                callBackResult.setMsg("创建成功");
            } catch (Exception e) {
                e.printStackTrace();
            }
            return callBackResult;
        });


    }

    /**
     * 去除提交过程中的空值
     *
     * @param adminUser
     * @return
     */
    private void setAdminGroups(String[] adminGroups, AdminUser adminUser) {
        List<AdminGroup> adminGroups2 = new ArrayList<>();
        if (adminGroups.length > 0) {
            for (String adminGroup1 : adminGroups) {
                AdminGroup adminGroup = adminGroupService.get(adminGroup1);
                adminGroups2.add(adminGroup);
            }
        }
        adminUser.setAdminGroup(adminGroups2);
    }

    @RequiresPermissions("admin:user:update")
    @RequestMapping(value = "update", method = RequestMethod.GET)
    public String update(@RequestParam(value = "id", required = false) String id, Map<String, Object> map) throws IOException {

        AdminUser adminUser = adminUserService.get(id);
        map.put("adminGroups", getAdminGroups());
        // 格式化处室
        String siteid = adminUser.getSiteid();
        if (ValidateUtil.isValid(siteid)) {
            ObjectMapper mapper = new ObjectMapper();
            @SuppressWarnings("unchecked")
            List<String> siteids = mapper.readValue(siteid, List.class);
            adminUser.setSiteids(siteids);
        }

        map.put("adminUser", adminUser);
        map.put("sexs", DataValues.sexs);
        return forward("/admin/admin-user/save-input.jsp");
    }

    @ResponseBody
    @RequiresPermissions("admin:user:update")
    @RequestMapping(value = "update", method = RequestMethod.POST)
    public ControllerUtils.CallBackResult update(
            @Validated AdminUser adminUser,
            BindingResult result,
            @RequestParam(value = "password_c", required = false) String password_c,
            @RequestParam(value = "sign", required = false) Boolean sign,
            @RequestParam(value = "adminGroups", required = false) String[] adminGroups)
            throws Exception {

        return new ControllerUtils().ajaxPostResult(result, callBackResult -> {
            setAdminGroups(adminGroups, adminUser);

            if (ValidateUtil.isValid(sign) && sign) {
                adminUser.setSignCode(FilesUtil.getUUIDName("", true));
            }
            // 处理提交过来的用户密码
            if (ValidateUtil.isValid(password_c)) {
                adminUser.setPassword(DigestUtils.sha1Hex(password_c));
            }
            if (ValidateUtil.isValid(adminUser.getSiteids())) {
                ObjectMapper objectMapper = new ObjectMapper();
                String siteid = null;
                try {
                    siteid = objectMapper.writeValueAsString(adminUser.getSiteids());
                } catch (JsonProcessingException e) {
                    e.printStackTrace();
                }
                adminUser.setSiteid(siteid);
            }
            adminUserService.update(adminUser);
            callBackResult.setMsg("修改完成");
            return callBackResult;
        });


    }

    /**
     * 删除
     *
     * @return
     */
    @RequiresPermissions("admin:user:delete")
    @ResponseBody
    @RequestMapping(value = "delete", method = RequestMethod.POST)
    public Map<String, Object> delete(@RequestParam("delid") String[] delid,
                                      @RequestParam("menuType") String menuType,
                                      @RequestParam("menuValue") String menuValue) {
        // code 小于1表示有错误,大于0表示ok,==0表示未操作
        Map<String, Object> ajaxResult = new HashMap<>();
        switch (menuType) {
            case "delete":
                ControllerUtils.delete(ajaxResult, adminUserService, delid);
                break;
            case "enabled":

                try {
                    for (String string : delid) {
                        AdminUser adminUser = adminUserService.get(string);
                        adminUser.setEnabled(DataUtil.stringToBoolean(menuValue));
                        adminUserService.update(adminUser);
                    }

                    ajaxResult.put("code", 1);
                    ajaxResult.put("msg", "success");
                } catch (Exception e) {
                    ajaxResult.put("code", -1);
                    ajaxResult.put("msg", e.getMessage());
                }

                break;
            case "locked":
                try {
                    for (String string : delid) {
                        AdminUser adminUser = adminUserService.get(string);
                        adminUser.setLocked(DataUtil.stringToBoolean(menuValue));
                        adminUserService.update(adminUser);
                    }

                    ajaxResult.put("code", 1);
                    ajaxResult.put("msg", "success");
                } catch (Exception e) {
                    ajaxResult.put("code", -1);
                    ajaxResult.put("msg", e.getMessage());
                }
                break;

            default:
                break;
        }

        return ajaxResult;

    }

    @RequiresPermissions("admin:user:ajaxUserList")
    @ResponseBody
    @RequestMapping("ajaxUserList")
    public List<Map<String, String>> ajaxUserList(@RequestParam("term") String term) {

        List<Map<String, String>> ajaxMaps = new ArrayList<>();
        if (ValidateUtil.isValid(term)) {
            List<AdminUser> lists = adminUserService.listByEmail("%" + term + "%");
            if (ValidateUtil.isValid(lists)) {
                for (AdminUser u : lists) {
                    Map<String, String> map = new HashMap<>();
                    map.put("id", String.valueOf(u.getId()));
                    map.put("label", u.getName());
                    map.put("value", u.getEmail());
                    ajaxMaps.add(map);
                }
            }
        }
        return ajaxMaps;
    }


}